package com.garbuz.svnadmin;

import common.serialization.Serializer;
import org.apache.commons.codec.binary.Base64;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class ApplicationServlet extends HttpServlet
{
	private static final long serialVersionUID = 1L;

	public ApplicationServlet()
	{
		super();
	}

	public void init()
	{
		if (AdminApplication.getInstance() == null)
		{
			try
			{
				AdminApplication.createInstance(getServletContext());
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
		}
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException
	{
		processRequest(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException
	{
		processRequest(request, response);
	}

	private void processRequest(HttpServletRequest request, HttpServletResponse response)
			throws IOException
	{
		try
		{
			Object[] requestParams = readRequestParams(request);

			String serviceName = (String) requestParams[0];
			String methodName = (String) requestParams[1];
			Object methodArgs[] = (Object[]) requestParams[2];

			ServiceInvoker invoker = new ServiceInvoker("com.garbuz.svnadmin.services");
			Object result = invoker.invoke(serviceName, methodName, methodArgs);

			if (invoker.successful())
				writeResult(response, result);
			else
				writeError(response, invoker.getError());
		}
		catch (Throwable e)
		{
			e.printStackTrace();
			writeError(response, e);
		}
	}

	private Object[] readRequestParams(HttpServletRequest request) throws Exception
	{
		String rawData = request.getParameter("data");
		byte[] bytes = Base64.decodeBase64(rawData);
		return (Object[]) Serializer.decode(bytes);
	}

	private void writeError(HttpServletResponse response, Throwable error) throws IOException
	{
		PrintWriter writer = response.getWriter();
		writer.write("!");

		if (error instanceof SvnModelError)
			writer.write(error.getMessage());
		else
			writer.write(ServiceInvoker.getErrorText(error, "com.garbuz"));
	}

	private void writeResult(HttpServletResponse response, Object result) throws Exception
	{
		byte[] resultBytes = Serializer.encode(result);
		String responseData = Base64.encodeBase64String(resultBytes);

		PrintWriter writer = response.getWriter();
		writer.write("@");
		writer.write(responseData);
	}
}
